use crate::error::AppError;
use crate::models::ai::config;
use crate::routes::handler::RouteHandler;
use crate::routes::payload::Payload;
use crate::routes::response::Response;
use crate::schemas::base::{FilterItem, ListResult, OneEffect, OneResultId};
use crate::{convert_vec, db, extract_payload, schemas};
use async_trait::async_trait;

pub struct CreateAiConfig;

#[async_trait]
impl RouteHandler for CreateAiConfig {
    async fn handle(&self, payload: Payload) -> Result<Response, AppError> {
        let data = extract_payload!(payload, Payload::CreateAiConfig)?;
        // 插入 ai_config 对象
        let entity: config::ActiveModel = data.clone().into();
        let new_entity = db::create::one("app", entity).await?;

        // 返回对象
        let new_datasource: schemas::ai::ListItem = new_entity.into();
        Ok(Response::AiConfigEffect(OneEffect {
            effect: new_datasource,
        }))
    }
}

pub struct ListAiConfig;

#[async_trait]
impl RouteHandler for ListAiConfig {
    async fn handle(&self, payload: Payload) -> Result<Response, AppError> {
        let query = extract_payload!(payload, Payload::ListQuery)?;
        let config_list = db::read::list::<config::Entity, config::Model>("app", query).await?;
        let result: Vec<schemas::ai::ListItem> = convert_vec!(config_list.result);
        Ok(Response::ListAiConfig(ListResult {
            total: config_list.total,
            result,
        }))
    }
}

pub struct UpdateAiConfig;

#[async_trait]
impl RouteHandler for UpdateAiConfig {
    async fn handle(&self, payload: Payload) -> Result<Response, AppError> {
        let data = extract_payload!(payload, Payload::UpdateAiConfig)?;
        let entity: config::ActiveModel = data.clone().into();
        let result = db::update::by_id("app", entity.clone(), data.id.clone()).await?;
        Ok(Response::OneResultId(OneResultId { id: result }))
    }
}

pub struct DeleteAiConfig;

#[async_trait]
impl RouteHandler for DeleteAiConfig {
    async fn handle(&self, payload: Payload) -> Result<Response, AppError> {
        let data = extract_payload!(payload, Payload::OperateAiConfig)?;
        let result =
            db::delete::by_id::<config::Entity, config::ActiveModel>("app", data.id).await?;

        Ok(Response::AiConfigEffectByString(OneResultId { id: result }))
    }
}

pub struct CurrentUseAiConfig;

#[async_trait]
impl RouteHandler for CurrentUseAiConfig {
    async fn handle(&self, _payload: Payload) -> Result<Response, AppError> {
        let filter = Some(vec![FilterItem {
            field: "current_use".into(),
            func: schemas::base::FilterFunc::EQ,
            value: Some(schemas::base::FilterValue::Int(1)),
        }]);
        let entity = db::read::one::<config::Entity>("app", filter).await?;
        Ok(Response::AiConfigEffect(OneEffect {
            effect: entity.into(),
        }))
    }
}

pub struct SetCurrentAiConfig;

#[async_trait]
impl RouteHandler for SetCurrentAiConfig {
    async fn handle(&self, payload: Payload) -> Result<Response, AppError> {
        let data = extract_payload!(payload, Payload::OperateAiConfig)?;
        // 现将所有数据置为未启用
        let update_data = config::ActiveModel {
            current_use: sea_orm::Set(Some(0)),
            ..Default::default()
        };
        db::update::by_filter("app", update_data, None).await?;
        // 启用选中的数据
        let result = db::update::by_id(
            "app",
            config::ActiveModel {
                current_use: sea_orm::Set(Some(1)),
                ..Default::default()
            },
            data.id,
        )
        .await?;

        Ok(Response::OneResultId(OneResultId { id: result }))
    }
}
